package br.com.jvet.entidade;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import br.com.jvet.constante.EstadoCivil;
import br.com.jvet.constante.GrauEscolaridade;
import br.com.jvet.constante.Sexo;
import br.com.jvet.constante.Situacao;
import br.com.jvet.constante.TipoCadastro;
import br.com.jvet.constante.TipoDeficiencia;
import br.com.jvet.constante.TipoPessoa;

@Entity
@Table(name = "tbfuncionario")
@SequenceGenerator(name = "func_seq", sequenceName = "func_seq", initialValue = 1000, allocationSize = 1)
public class Funcionario implements Serializable {

	private static final long serialVersionUID = 1058547188107449698L;
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "func_seq")
	private int matricula;
	@OneToOne(cascade = CascadeType.ALL)
	private DadosCadastro dadosCadastro;
	@OneToOne
	private Cargo cargo;
	@Column(precision = 2)
	private double salarioBase;
	@Column(name = "estado_civil")
	@Enumerated(EnumType.ORDINAL)
	private EstadoCivil estadoCivil;
	@Column(length = 80)
	private String nomePai;
	@Column(length = 80)
	private String nomeMae;
	@Embedded
	private TituloEleitor tituloEleitor;
	@Embedded
	private CarteiraTrabalho carteiraTrabalho;
	@Column
	@Enumerated(EnumType.ORDINAL)
	private GrauEscolaridade grauEscolaridade;
	@Column
	@Temporal(TemporalType.DATE)
	private Date dataAdmissao;
	@Temporal(TemporalType.DATE)
	private Date dataDemissao;
	@Enumerated(EnumType.ORDINAL)
	private Situacao situacao;
	@Column
	private boolean possuiDeficiencia;
	@Column
	private TipoDeficiencia tipoDeficiencia;
	@Column
	@Temporal(TemporalType.TIME)
	private Date horaEntrada;
	@Column
	@Temporal(TemporalType.TIME)
	private Date horaSaida;
	@Embedded
	private DadoBancario dadoBancario;
	@OneToOne(cascade = CascadeType.ALL, optional = true)
	private MedicoVeterinario medico;
	@Column(length = 200)
	private String observacao;

	public Funcionario() {
		super();
		dadosCadastro = new DadosCadastro();
		dadosCadastro.setTipoCadastro(TipoCadastro.FUNCIONARIO);
		dadosCadastro.setTipoPessoa(TipoPessoa.FISICA);
		dadosCadastro.setSexo(Sexo.MASCULINO);
		setEstadoCivil(EstadoCivil.SOLTEIRO);
		setPossuiDeficiencia(false);
		cargo = new Cargo();
		carteiraTrabalho = new CarteiraTrabalho();
		tituloEleitor = new TituloEleitor();
		dadoBancario = new DadoBancario();
		medico = new MedicoVeterinario();

	}

	public int getMatricula() {
		return matricula;
	}

	public void setMatricula(int matricula) {
		this.matricula = matricula;
	}

	public DadosCadastro getDadosCadastro() {
		return dadosCadastro;
	}

	public void setDadosCadastro(DadosCadastro dadosCadastro) {
		this.dadosCadastro = dadosCadastro;
	}

	public Cargo getCargo() {
		return cargo;
	}

	public void setCargo(Cargo cargo) {
		this.cargo = cargo;
	}

	public double getSalarioBase() {
		return salarioBase;
	}

	public void setSalarioBase(double salarioBase) {
		this.salarioBase = salarioBase;
	}

	public EstadoCivil getEstadoCivil() {
		return estadoCivil;
	}

	public void setEstadoCivil(EstadoCivil estadoCivil) {
		this.estadoCivil = estadoCivil;
	}

	public String getNomePai() {
		return nomePai;
	}

	public void setNomePai(String nomePai) {
		this.nomePai = nomePai;
	}

	public String getNomeMae() {
		return nomeMae;
	}

	public void setNomeMae(String nomeMae) {
		this.nomeMae = nomeMae;
	}

	public TituloEleitor getTituloEleitor() {
		return tituloEleitor;
	}

	public void setTituloEleitor(TituloEleitor tituloEleitor) {
		this.tituloEleitor = tituloEleitor;
	}

	public CarteiraTrabalho getCarteiraTrabalho() {
		return carteiraTrabalho;
	}

	public void setCarteiraTrabalho(CarteiraTrabalho carteiraTrabalho) {
		this.carteiraTrabalho = carteiraTrabalho;
	}

	public GrauEscolaridade getGrauEscolaridade() {
		return grauEscolaridade;
	}

	public void setGrauEscolaridade(GrauEscolaridade grauEscolaridade) {
		this.grauEscolaridade = grauEscolaridade;
	}

	public Date getDataAdmissao() {
		return dataAdmissao;
	}

	public void setDataAdmissao(Date dataAdmissao) {
		this.dataAdmissao = dataAdmissao;
	}

	public Date getDataDemissao() {
		return dataDemissao;
	}

	public void setDataDemissao(Date dataDemissao) {
		this.dataDemissao = dataDemissao;
	}

	public Situacao getSituacao() {
		return situacao;
	}

	public void setSituacao(Situacao situacao) {
		this.situacao = situacao;
	}

	public boolean isPossuiDeficiencia() {
		return possuiDeficiencia;
	}

	public void setPossuiDeficiencia(boolean possuiDeficiencia) {
		this.possuiDeficiencia = possuiDeficiencia;
	}

	public TipoDeficiencia getTipoDeficiencia() {
		return tipoDeficiencia;
	}

	public void setTipoDeficiencia(TipoDeficiencia tipoDeficiencia) {
		this.tipoDeficiencia = tipoDeficiencia;
	}

	public Date getHoraEntrada() {
		return horaEntrada;
	}

	public void setHoraEntrada(Date horaEntrada) {
		this.horaEntrada = horaEntrada;
	}

	public Date getHoraSaida() {
		return horaSaida;
	}

	public void setHoraSaida(Date horaSaida) {
		this.horaSaida = horaSaida;
	}

	public DadoBancario getDadoBancario() {
		return dadoBancario;
	}

	public void setDadoBancario(DadoBancario dadoBancario) {
		this.dadoBancario = dadoBancario;
	}

	public MedicoVeterinario getMedico() {
		return medico;
	}

	public void setMedico(MedicoVeterinario medico) {
		this.medico = medico;
	}

	public String getObservacao() {
		return observacao;
	}

	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((dadosCadastro == null) ? 0 : dadosCadastro.hashCode());
		result = prime * result + matricula;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Funcionario other = (Funcionario) obj;
		if (dadosCadastro == null) {
			if (other.dadosCadastro != null)
				return false;
		} else if (!dadosCadastro.equals(other.dadosCadastro))
			return false;
		if (matricula != other.matricula)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Funcionario [matricula=" + matricula + ", dadosCadastro="
				+ dadosCadastro + ", cargo=" + cargo + ", salarioBase="
				+ salarioBase + ", estadoCivil=" + estadoCivil + ", nomePai="
				+ nomePai + ", nomeMae=" + nomeMae + ", tituloEleitor="
				+ tituloEleitor + ", carteiraTrabalho=" + carteiraTrabalho
				+ ", grauEscolaridade=" + grauEscolaridade + ", dataAdmissao="
				+ dataAdmissao + ", dataDemissao=" + dataDemissao
				+ ", situacao=" + situacao + ", possuiDeficiencia="
				+ possuiDeficiencia + ", tipoDeficiencia=" + tipoDeficiencia
				+ ", horaEntrada=" + horaEntrada + ", horaSaida=" + horaSaida
				+ "]";
	}

	public Funcionario clone() {
		Funcionario func = new Funcionario();
		func.setCargo(cargo.clone());
		func.setCarteiraTrabalho(carteiraTrabalho);
		func.setDadosCadastro(dadosCadastro.clone());
		func.setDataAdmissao(dataAdmissao);
		func.setDataDemissao(dataDemissao);
		func.setEstadoCivil(estadoCivil);
		func.setGrauEscolaridade(grauEscolaridade);
		func.setHoraEntrada(horaEntrada);
		func.setHoraSaida(horaSaida);
		func.setMatricula(matricula);
		func.setNomeMae(nomeMae);
		func.setNomePai(nomePai);
		func.setPossuiDeficiencia(possuiDeficiencia);
		func.setSalarioBase(salarioBase);
		func.setSituacao(situacao);
		func.setTipoDeficiencia(tipoDeficiencia);
		func.setTituloEleitor(tituloEleitor);
		func.setDadoBancario(dadoBancario);
		func.setMedico(medico);
		return func;
	}
}
